import re
import csv
from datetime import datetime
import os

def parse_log_file(file_path):
    # 用于存储解析后的数据
    data = []
    
    # 正则表达式模式
    timestamp_pattern = r'\[(\d{2}:\d{2}:\d{2}\.\d{3})\]'
    tpask1_pattern = r'\$TPASK,1,1\*'
    # 修改正则表达式以正确捕获母节点1温度（第6个位置）
    tpdat1_pattern = r'\$TPDAT,1,(\w+),(?:\d+,){4}(\d+),'
    tpask3_pattern = r'\$TPASK,3,1\*'
    tpdat3_pattern = r'\$TPDAT,3,(\w+),(\d+),(\d+),(\d+)'
    
    current_timestamp = None
    current_data = {}
    
    with open(file_path, 'r', encoding='utf-8', errors='replace') as file:
        for line in file:
            # 提取时间戳
            timestamp_match = re.search(timestamp_pattern, line)
            if timestamp_match:
                line_timestamp = timestamp_match.group(1)
                
                # 检查TPASK,1请求
                if re.search(tpask1_pattern, line):
                    current_timestamp = line_timestamp
                    current_data = {'timestamp': current_timestamp}
                
                # 检查TPDAT,1响应
                tpdat1_match = re.search(tpdat1_pattern, line)
                if tpdat1_match and current_timestamp:
                    pressure1 = tpdat1_match.group(1)
                    temp1 = int(tpdat1_match.group(2))
                    # 保留原始十六进制压力值格式
                    current_data['pressure1'] = pressure1 
                    # 用于图表的十进制压力值
                    current_data['pressure1_dec'] = int(pressure1, 16)
                    # 只有当温度值不是9966时才计算，并保留2位小数
                    if temp1 != 9966:
                        temp1_value = round(temp1/100 - 20, 2)
                        # 只保存正温度值
                        if temp1_value >= 0:
                            current_data['temp1'] = temp1_value
                        else:
                            current_data['temp1'] = None
                    else:
                        current_data['temp1'] = None
                
                # 检查TPASK,3请求
                if re.search(tpask3_pattern, line):
                    pass  # 只是标记，不需要处理
                
                # 检查TPDAT,3响应
                tpdat3_match = re.search(tpdat3_pattern, line)
                if tpdat3_match and 'timestamp' in current_data:
                    pressure2 = tpdat3_match.group(1)
                    node2_temp1 = int(tpdat3_match.group(2))
                    node2_temp2 = int(tpdat3_match.group(3))
                    node2_temp3 = int(tpdat3_match.group(4))
                    
                    # 保留原始十六进制压力值格式
                    current_data['pressure2'] = pressure2
                    # 用于图表的十进制压力值
                    current_data['pressure2_dec'] = int(pressure2, 16)
                    
                    # 计算子节点和母节点温度，并保留2位小数，排除负值
                    temp_child1 = round(node2_temp1/100 - 20, 2)
                    temp_node2 = round(node2_temp2/100 - 20, 2)
                    temp_child2 = round(node2_temp3/100 - 20, 2)
                    
                    # 只保存正温度值
                    current_data['child1_temp'] = temp_child1 if temp_child1 >= 0 else None
                    current_data['node2_temp'] = temp_node2 if temp_node2 >= 0 else None
                    current_data['child2_temp'] = temp_child2 if temp_child2 >= 0 else None
                    
                    # 添加完整记录到数据列表
                    if 'pressure1' in current_data:
                        # 检查是否所有温度值都为负数或None
                        all_temps_negative = (
                            (current_data.get('temp1') is None) and
                            (current_data.get('child1_temp') is None) and
                            (current_data.get('node2_temp') is None) and
                            (current_data.get('child2_temp') is None)
                        )
                        
                        # 只有至少有一个温度值为正数时才添加数据
                        if not all_temps_negative:
                            # 格式化时间戳为简化格式
                            timestamp_parts = current_data['timestamp'].split(':')
                            short_ts = f"{timestamp_parts[0]}:{timestamp_parts[1]}.{timestamp_parts[2].split('.')[1][:1]}"
                            current_data['short_timestamp'] = short_ts
                            
                            # 添加完整的datetime对象用于图表
                            current_data['datetime'] = datetime.strptime(current_data['timestamp'], '%H:%M:%S.%f')
                            
                            data.append(current_data)
                        
                        current_data = {}
                        current_timestamp = None
    
    return data

def create_csv(data, output_file):
    # 定义列名
    fieldnames = [
        '时间戳', '母节点1压力', '母节点1温度', 
        '母节点2压力', '子节点1温度', '母节点2温度', '子节点2温度'
    ]
    
    # 写入CSV文件
    with open(output_file, 'w', newline='', encoding='utf-8-sig') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()
        
        for row in data:
            writer.writerow({
                '时间戳': row['short_timestamp'],
                '母节点1压力': row['pressure1'],
                '母节点1温度': row['temp1'],
                '母节点2压力': row['pressure2'],
                '子节点1温度': row['child1_temp'],
                '母节点2温度': row['node2_temp'],
                '子节点2温度': row['child2_temp']
            })
    
    print(f"数据已保存至 {output_file}")
    return

def generate_html_chart(data, output_prefix):
    """生成HTML格式的图表，不依赖matplotlib"""
    
    # 创建charts目录
    charts_dir = 'charts'
    if not os.path.exists(charts_dir):
        os.makedirs(charts_dir)
    
    # 准备数据
    timestamps = []
    temp_node1 = []
    temp_child1 = []
    temp_node2 = []
    temp_child2 = []
    pressure1 = []
    pressure2 = []
    
    for entry in data:
        ts = entry['short_timestamp']
        timestamps.append(ts)
        
        # 温度数据，None值用'null'表示
        temp_node1.append(str(entry['temp1']) if entry['temp1'] is not None else 'null')
        temp_child1.append(str(entry['child1_temp']) if entry['child1_temp'] is not None else 'null')
        temp_node2.append(str(entry['node2_temp']) if entry['node2_temp'] is not None else 'null')
        temp_child2.append(str(entry['child2_temp']) if entry['child2_temp'] is not None else 'null')
        
        # 压力数据
        pressure1.append(str(entry['pressure1_dec']))
        pressure2.append(str(entry['pressure2_dec']))
    
    # 构建温度图表HTML
    temp_chart_html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>温度随时间变化图</title>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    </head>
    <body>
        <div style="width:90%; margin:0 auto;">
            <canvas id="tempChart"></canvas>
        </div>
        
        <script>
            const ctx = document.getElementById('tempChart');
            
            new Chart(ctx, {{
                type: 'line',
                data: {{
                    labels: {str(timestamps)},
                    datasets: [
                        {{
                            label: '母节点1温度',
                            data: {str(temp_node1)},
                            borderColor: 'red',
                            tension: 0.1
                        }},
                        {{
                            label: '子节点1温度',
                            data: {str(temp_child1)},
                            borderColor: 'green',
                            tension: 0.1
                        }},
                        {{
                            label: '母节点2温度',
                            data: {str(temp_node2)},
                            borderColor: 'blue',
                            tension: 0.1
                        }},
                        {{
                            label: '子节点2温度',
                            data: {str(temp_child2)},
                            borderColor: 'orange',
                            tension: 0.1
                        }}
                    ]
                }},
                options: {{
                    responsive: true,
                    plugins: {{
                        title: {{
                            display: true,
                            text: '温度随时间变化图',
                            font: {{
                                size: 16
                            }}
                        }}
                    }},
                    scales: {{
                        y: {{
                            title: {{
                                display: true,
                                text: '温度 (°C)'
                            }}
                        }},
                        x: {{
                            title: {{
                                display: true,
                                text: '时间'
                            }}
                        }}
                    }}
                }}
            }});
        </script>
    </body>
    </html>
    """
    
    # 构建压力图表HTML
    pressure_chart_html = f"""
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>压力随时间变化图</title>
        <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    </head>
    <body>
        <div style="width:90%; margin:0 auto;">
            <canvas id="pressureChart"></canvas>
        </div>
        
        <script>
            const ctx = document.getElementById('pressureChart');
            
            new Chart(ctx, {{
                type: 'line',
                data: {{
                    labels: {str(timestamps)},
                    datasets: [
                        {{
                            label: '母节点1压力',
                            data: {str(pressure1)},
                            borderColor: 'red',
                            tension: 0.1
                        }},
                        {{
                            label: '母节点2压力',
                            data: {str(pressure2)},
                            borderColor: 'blue',
                            tension: 0.1
                        }}
                    ]
                }},
                options: {{
                    responsive: true,
                    plugins: {{
                        title: {{
                            display: true,
                            text: '压力随时间变化图',
                            font: {{
                                size: 16
                            }}
                        }}
                    }},
                    scales: {{
                        y: {{
                            title: {{
                                display: true,
                                text: '压力值'
                            }}
                        }},
                        x: {{
                            title: {{
                                display: true,
                                text: '时间'
                            }}
                        }}
                    }}
                }}
            }});
        </script>
    </body>
    </html>
    """
    
    # 写入HTML文件
    temp_chart_path = os.path.join(charts_dir, f"{output_prefix}_temperature.html")
    with open(temp_chart_path, 'w', encoding='utf-8') as f:
        f.write(temp_chart_html)
    
    pressure_chart_path = os.path.join(charts_dir, f"{output_prefix}_pressure.html")
    with open(pressure_chart_path, 'w', encoding='utf-8') as f:
        f.write(pressure_chart_html)
    
    print(f"HTML图表已保存至 {charts_dir} 目录：")
    print(f"  - 温度图表：{temp_chart_path}")
    print(f"  - 压力图表：{pressure_chart_path}")
    
    return

def main():
    input_file = 'SaveWindows2025_4_3_16-30-28.TXT'
    output_csv = 'processed_data_filtered.csv'
    chart_prefix = 'data'
    
    # 解析日志文件
    data = parse_log_file(input_file)
    
    # 创建CSV文件
    create_csv(data, output_csv)
    
    # 生成HTML图表
    try:
        generate_html_chart(data, chart_prefix)
    except Exception as e:
        print(f"生成图表时发生错误: {e}")
        print("您可以使用Excel或其他工具打开CSV文件手动创建图表。")
    
    print(f"处理完成。共处理 {len(data)} 条数据记录。")

if __name__ == "__main__":
    main() 